package com.xb.loan.util.qrtz.task;


import com.xb.loan.util.qrtz.TaskScheduleManager;
import com.xb.loan.util.qrtz.common.Constants;
import com.xb.loan.util.qrtz.common.store.TaskEntiryStoreSupport;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * 
 *任务抽象类
 * @author wuql
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public abstract class AbstractTask extends QuartzJobBean implements Task,Constants {
    
    /**
     * 彩种id
     */
    private String game_id;
    /**
     * 期次id
     */
    private String issue_id;
	private String jobName;
	private String jobGroup = "default";
	/**
	 *  任务因实例故障退出，实例重启后是是否要恢复当前任务，simple任务一般为true，cron任务一般false, 有 misfireHandle处理
	 */
	protected boolean requestRecovery;
	private Map<String, Object> params = new HashMap<String, Object>();
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 执行完的jobdetail 是否要存储
	 */
	protected boolean storeDurably=false;
	
	private TaskScheduleManager taskScheduleManager;
	
	public AbstractTask(String jobName) {
		this.jobName = jobName;
	}
	public AbstractTask() {
	}
	
	public TaskScheduleManager getTaskScheduleManager() {
		return taskScheduleManager;
	}
	public void setTaskScheduleManager(TaskScheduleManager taskScheduleManager) {
		this.taskScheduleManager = taskScheduleManager;
	}

    public String getGame_id() {
        return game_id;
    }

    public void setGame_id(String game_id) {
        this.game_id = game_id;
    }

    public String getIssue_id() {
        return issue_id;
    }

    public void setIssue_id(String issue_id) {
        this.issue_id = issue_id;
    }
	public boolean isStoreDurably() {
		return storeDurably;
	}
	public void setStoreDurably(boolean storeDurably) {
		this.storeDurably = storeDurably;
	}
	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}

	public String getJobName() {
		return jobName;
	}

	public void setJobName(String jobName) {
		this.jobName = jobName;
	}

	public String getJobGroup() {
		return jobGroup;
	}

	public void setJobGroup(String jobGroup) {
		this.jobGroup = jobGroup;
	}

	public boolean isRequestRecovery() {
		return requestRecovery;
	}

	public void setRequestRecovery(boolean requestRecovery) {
		this.requestRecovery = requestRecovery;
	}

	public Class getProcessClass() {
		return getClass();
	}

	public void schedule(Task task) throws SchedulerException {
		shedule(task);
	}

	public void schedule(String taskId, Class<? extends Task> clazz, String cron, Map<String, Object> params) {
		taskScheduleManager.shedule(taskId, clazz, cron, params);
		
	}

    private boolean shedule(Task task) throws SchedulerException {
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
        }
        return taskScheduleManager.shedule(task);
    }


    public <T> T getSpringBean(String beanId) {
        return (T) taskScheduleManager.getBean(beanId);
    }
	
	public TaskEntiryStoreSupport getTaskStoreSupport()
	{
		return getSpringBean(taskStoreSupportBean);
	}

	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		if (taskScheduleManager == null) {
			try {
				ApplicationContext appContext = (ApplicationContext) context.getScheduler().getContext()
						.get(applicationContext);
				taskScheduleManager = (TaskScheduleManager) appContext.getBean(taskScheduleManagerBean);
				setTaskScheduleManager(taskScheduleManager);
			} catch (SchedulerException e) {
				logger.error("", e);
			}
		}
		if (jobName == null || "".equals(jobName)) {
			jobName = context.getJobDetail().getKey().getName();
			jobGroup=context.getJobDetail().getKey().getGroup();
		}
		if(params.isEmpty())
		{
			JobDataMap tempMap = context.getJobDetail().getJobDataMap();
			for(String key :tempMap.keySet())
			{
				params.put(key, tempMap.get(key));
			}
		}
		
		taskScheduleManager.getTaskListenerSupport().fireTaskToBeExecuted(this);
		run();
		taskScheduleManager.getTaskListenerSupport().fireTaskWasExecuted(this);
	}
	
	
	
    public String getTaskEntityId() {
        return  jobName + "$" + jobGroup;
    }
    public abstract void run();

}
